From edd5d36159df7e88d1c295ad8fd2f1f6fe52aad9 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 3 May 2020 10:50:56 -0400 Subject: [PATCH] overlay: Derive from GtkWidget We want to remove GtkBin and GtkContainer as they don't provide much useful functionality anymore. See #2681 --- gtk/gtkoverlay.c | 121 +++++++++++++++++++++-------------------------- gtk/gtkoverlay.h | 2 +- 2 files changed, 56 insertions(+), 67 deletions(-) diff --git a/gtk/gtkoverlay.c b/gtk/gtkoverlay.c index 45277bad44..6d4962dbb6 100644 --- a/gtk/gtkoverlay.c +++ b/gtk/gtkoverlay.c @@ -83,19 +83,21 @@ typedef struct _GtkOverlayClass GtkOverlayClass; struct _GtkOverlay { - GtkBin parent_instance; + GtkWidget parent_instance; + + GtkWidget *child; }; struct _GtkOverlayClass { - GtkBinClass parent_class; + GtkWidgetClass parent_class; gboolean (*get_child_position) (GtkOverlay *overlay, GtkWidget *widget, GtkAllocation *allocation); }; -G_DEFINE_TYPE_WITH_CODE (GtkOverlay, gtk_overlay, GTK_TYPE_BIN, +G_DEFINE_TYPE_WITH_CODE (GtkOverlay, gtk_overlay, GTK_TYPE_WIDGET, G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, gtk_overlay_buildable_init)) @@ -183,54 +185,6 @@ gtk_overlay_get_child_position (GtkOverlay *overlay, return TRUE; } -static void -gtk_overlay_add (GtkContainer *container, - GtkWidget *widget) -{ - - /* We only get into this path if we have no child - * (since GtkOverlay is a GtkBin) and the only child - * we can add through gtk_container_add is the main child, - * which we want to keep the lowest in the hierarchy. - */ - gtk_widget_insert_after (widget, GTK_WIDGET (container), NULL); - _gtk_bin_set_child (GTK_BIN (container), widget); -} - -static void -gtk_overlay_remove (GtkContainer *container, - GtkWidget *widget) -{ - GtkWidget *main_child = gtk_bin_get_child (GTK_BIN (container)); - - if (widget == main_child) - { - GTK_CONTAINER_CLASS (gtk_overlay_parent_class)->remove (container, widget); - } - else - { - gtk_widget_unparent (widget); - } -} - -static void -gtk_overlay_forall (GtkContainer *overlay, - GtkCallback callback, - gpointer callback_data) -{ - GtkWidget *child; - - child = gtk_widget_get_first_child (GTK_WIDGET (overlay)); - while (child != NULL) - { - GtkWidget *next = gtk_widget_get_next_sibling (child); - - (* callback) (child, callback_data); - - child = next; - } -} - static void gtk_overlay_snapshot_child (GtkWidget *overlay, GtkWidget *child, @@ -310,21 +264,54 @@ gtk_overlay_set_property (GObject *object, } } +static void +gtk_overlay_dispose (GObject *object) +{ + GtkOverlay *overlay = GTK_OVERLAY (object); + GtkWidget *child; + + g_clear_pointer (&overlay->child, gtk_widget_unparent); + + while ((child = gtk_widget_get_first_child (GTK_WIDGET (overlay)))) + gtk_widget_unparent (child); + + G_OBJECT_CLASS (gtk_overlay_parent_class)->dispose (object); +} + +static void +gtk_overlay_compute_expand (GtkWidget *widget, + gboolean *hexpand, + gboolean *vexpand) +{ + GtkOverlay *overlay = GTK_OVERLAY (widget); + + if (overlay->child) + { + *hexpand = gtk_widget_compute_expand (overlay->child, GTK_ORIENTATION_HORIZONTAL); + *vexpand = gtk_widget_compute_expand (overlay->child, GTK_ORIENTATION_VERTICAL); + } + else + { + *hexpand = FALSE; + *vexpand = FALSE; + } +} + static void gtk_overlay_class_init (GtkOverlayClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); - GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass); + + object_class->dispose = gtk_overlay_dispose; object_class->get_property = gtk_overlay_get_property; object_class->set_property = gtk_overlay_set_property; widget_class->snapshot = gtk_overlay_snapshot; - - container_class->add = gtk_overlay_add; - container_class->remove = gtk_overlay_remove; - container_class->forall = gtk_overlay_forall; + widget_class->compute_expand = gtk_overlay_compute_expand; + widget_class->grab_focus = gtk_widget_grab_focus_none; + widget_class->focus = gtk_widget_focus_child; klass->get_child_position = gtk_overlay_get_child_position; @@ -396,11 +383,7 @@ gtk_overlay_buildable_add_child (GtkBuildable *buildable, if (type && strcmp (type, "overlay") == 0) gtk_overlay_add_overlay (GTK_OVERLAY (buildable), GTK_WIDGET (child)); else if (!type) - { - /* Make sure the main-child node is the first one */ - gtk_widget_insert_after (GTK_WIDGET (child), GTK_WIDGET (buildable), NULL); - _gtk_bin_set_child (GTK_BIN (buildable), GTK_WIDGET (child)); - } + gtk_overlay_set_child (GTK_OVERLAY (buildable), GTK_WIDGET (child)); else GTK_BUILDER_WARN_INVALID_CHILD_TYPE (buildable, type); } @@ -572,10 +555,16 @@ gtk_overlay_set_child (GtkOverlay *overlay, g_return_if_fail (GTK_IS_OVERLAY (overlay)); g_return_if_fail (child == NULL || GTK_IS_WIDGET (child)); - if (gtk_bin_get_child (GTK_BIN (overlay))) - gtk_container_remove (GTK_CONTAINER (overlay), gtk_bin_get_child (GTK_BIN (overlay))); - else - gtk_container_add (GTK_CONTAINER (overlay), child); + g_clear_pointer (&overlay->child, gtk_widget_unparent); + + overlay->child = child; + + if (child) + { + /* Make sure the main-child node is the first one */ + gtk_widget_insert_after (child, GTK_WIDGET (overlay), NULL); + } + g_object_notify (G_OBJECT (overlay), "child"); } @@ -592,5 +581,5 @@ gtk_overlay_get_child (GtkOverlay *overlay) { g_return_val_if_fail (GTK_IS_OVERLAY (overlay), NULL); - return gtk_bin_get_child (GTK_BIN (overlay)); + return overlay->child; } diff --git a/gtk/gtkoverlay.h b/gtk/gtkoverlay.h index 65b0412b36..f24365c8a4 100644 --- a/gtk/gtkoverlay.h +++ b/gtk/gtkoverlay.h @@ -25,7 +25,7 @@ #error "Only can be included directly." #endif -#include +#include G_BEGIN_DECLS -- 2.30.2